#include "mat2array.h"

Converter::Converter(cv::Size data_sz, int nchannels) {
// Currently only converts from cv::Mat to af::array

	// array dimentions
	sz = af::dim4(data_sz.height, data_sz.width, nchannels);

	// pre-compute indices for conversion 
	af::seq s1(sz[2] - 1, sz[2], sz[1] * sz[2] - 1);
	ind = af::join(0, af::array(s1), af::array(s1-1), af::array(s1-2));

	// allocate pinned host memory
	allocateMemory();
}

void Converter::allocateMemory() {
	size_t num_elems = sz[0] * sz[1] * sz[2];

	// allocate pinned host memory for data 
	dataPtr = af::array::pinned<float>(num_elems); 

	// create Mat in the allocated memory
	data_float = cv::Mat(sz[0], sz[1], CV_32FC3, dataPtr);
}

af::array Converter::to_array(cv::Mat data) {

   // convert the Mat elements to float
	data.convertTo(data_float, CV_32F);
   
   // create GPU array from Mat
	af::array output = af::array(sz[1] * sz[2], sz[0], dataPtr).T();
   
   // rearrange array data 
	return af::array(output(af::span, ind), sz);
}